using System;
using Gtk;
using System.Collections.Generic;
using DaphneTranslator;
using DaphneTranslator.BusinessLogic;
using System.ComponentModel;
using System.Collections;

namespace DaphneTranslator
{
	public class LanguageDataRecord
	{
		public string Key
		{ get; set; }
		
		public string FirstLanguage
		{ get; set; }
		
		public string SecondLanguage
		{ get; set; }
	}
	
	
	[System.ComponentModel.ToolboxItem(true)]
	public partial class LanguageWidget : Gtk.Bin
	{
		private DataGrid _dataGrid;
		private string clrWhite = "#FFFFFF";
		private string clrMissingSecond = "#FFFF00" ;
		private string clrMissingFirst = "#FF0000";
		
		private LanguageFile _primaryLanguage;
		private LanguageFile _secondaryLanguage;
		
		public event TChangeOccured ChangeOccuredEvent;
		public event TNewTextRequestDelegate NewTextRequestEvent;
		
		
		public LanguageWidget ()
		{
			this.Build ();
			
			_dataGrid = new DataGrid ();
			_dataGrid.SetColumnCount (3);
			_dataGrid.AppendColumn (_dataGrid.CreateColumn (0, "Key", "Key", "#C8BFE7"));
			_dataGrid.AppendColumn (_dataGrid.CreateColumn (1, "First language", "FirstLanguage", "#C8BFE7"));
			_dataGrid.AppendColumn (_dataGrid.CreateColumn (2, "Second language", "SecondLanguage", string.Empty, true));				
			
			cbxFilter.InsertText (0, "Display all texts");
			cbxFilter.InsertText (1, "Display only missing texts.");
			cbxFilter.Changed += FilterChanged;
			
			vboxDataGridContainer.Add (_dataGrid);
			
			_dataGrid.UpdateRowEvent += HandleUpdateRowEvent;
			_dataGrid.ContextMenuEvent += HandleContextMenuEvent;
			buttonAddNewText.Clicked += HandleAddNewTextEvent;
		}


		void HandleAddNewTextEvent (object sender, EventArgs e)
		{
			if (NewTextRequestEvent != null) {
				NewTextRequestEvent ();
			}			
		}
		
		private void RaiseChangedOccured ()
		{
			if (ChangeOccuredEvent != null) {
				ChangeOccuredEvent ();
			}
		}

		void HandleUpdateRowEvent (object obj, string sPropertyName, string sValue)
		{
			if (obj == null)
				return;
			if (! (obj is LanguageDataRecord))
				return;
			
			if (sPropertyName != "SecondLanguage")
				return;
			
			LanguageDataRecord rec = obj as LanguageDataRecord;		   

			LanguageText sec = _secondaryLanguage.FindTextByKey (rec.Key);
			if (sec == null) {
				sec = new LanguageText ();
				sec.Key = rec.Key;
				LanguageText prim = _primaryLanguage.FindTextByKey (rec.Key);
				if (prim == null)
					return;
				sec.ValueXmlKey = prim.ValueXmlKey;
				_secondaryLanguage.Texts.Add (sec);
			}
			
			sec.Value = sValue;
			
			RaiseChangedOccured ();
			
		}
		
		void HandleContextMenuEvent (object obj, string sPropertyName)
		{
			// primary checks whether to display context menu
			if (obj == null)
				return;
			if (! (obj is LanguageDataRecord))
				return;
			
			if (sPropertyName != "FirstLanguage")
				return;
			
			LanguageDataRecord rec = obj as LanguageDataRecord;
			if (string.IsNullOrWhiteSpace (rec.FirstLanguage) == false)
				return;
			
			// create the menu
			Menu menu = new Menu ();
			MenuItem menuNew = new MenuItem ("Complete primary language text");
			menuNew.Activated += delegate(object sender, EventArgs e) {
				HandleCompletingText (rec);
			};
			menu.Append (menuNew);
			
			// show the menu
			menu.ShowAll ();
			menu.Popup ();						
		}
		
		private void HandleCompletingText (LanguageDataRecord rec)
		{
			CompleteTextDialog dlg = new CompleteTextDialog ();
			ResponseType res = (ResponseType)dlg.Run ();
			if (res == ResponseType.Ok) {
				LanguageText text = new LanguageText ();
				text.Key = rec.Key;
				foreach (var item in _secondaryLanguage.Texts) {
					if (item.Key == text.Key) {
						text.ValueXmlKey = item.ValueXmlKey;
					}
				}
				text.Value = dlg.GetText ();
				_primaryLanguage.Texts.Add (text);
				
					
				rec.FirstLanguage = dlg.GetText ();
				Refresh ();
			}
			dlg.Destroy ();		
		}
		

		void FilterChanged (object sender, EventArgs e)
		{
			int sel = cbxFilter.Active;
			if (sel == 0) {
				_dataGrid.FilterRows ((obj) => {
					return true; }
				);				
			} else {
				_dataGrid.FilterRows ((obj) =>
				{
					LanguageDataRecord rec = obj as LanguageDataRecord;
					string sPrimary = rec.FirstLanguage;
					string sSecondary = rec.SecondLanguage;
					return string.IsNullOrWhiteSpace (sPrimary) == true || 
						string.IsNullOrWhiteSpace (sSecondary) == true;
				}
				);				
			}	
			
			UpdateRowColors ();
		}
		
		public void SetLanguages (LanguageFile primaryLang, LanguageFile secondaryLang)
		{
			_primaryLanguage = primaryLang;
			_secondaryLanguage = secondaryLang;
			
			// create data source
			cbxFilter.Active = 0;
			List<LanguageText> lstFoundTexts = new List<LanguageText> ();
			
			List<LanguageDataRecord> list = new List<LanguageDataRecord> ();
			foreach (var item in primaryLang.Texts) {
				LanguageDataRecord rec = new LanguageDataRecord ();
				rec.Key = item.Key;
				rec.FirstLanguage = item.Value;
				rec.SecondLanguage = string.Empty;
				
				foreach (var subItem in secondaryLang.Texts) {
					if (subItem.Key == item.Key) {
						rec.SecondLanguage = subItem.Value;
						lstFoundTexts.Add (subItem);
						break;
					}
				}	
				
			
				list.Add (rec);
			}
			
			// add keys missing in the primary language
			foreach (var item in secondaryLang.Texts) {
				if (lstFoundTexts.Contains (item) == false) {
					LanguageDataRecord rec = new LanguageDataRecord ();
					rec.Key = item.Key;
					rec.FirstLanguage = string.Empty;
					rec.SecondLanguage = item.Value;
					
					list.Add (rec);
				}
			}
			
			// bind it
			_dataGrid.DataSource = list;
			_dataGrid.DataBind ();		
			
			// update row colors
			UpdateRowColors ();
		}	
		
		public void Refresh ()
		{
			SetLanguages (_primaryLanguage, _secondaryLanguage);			
		}
		
		private void UpdateRowColors ()
		{
			ListStore store = _dataGrid.Store;
			TreeIter iter = new TreeIter ();
			if (store.GetIterFirst (out iter)) {
				do {
					string sPrimary = (string)store.GetValue (iter, 1);
					string sSecondary = (string)store.GetValue (iter, 2);
					if (string.IsNullOrWhiteSpace (sPrimary))
						_dataGrid.SetRowColor (iter, clrMissingFirst, true);
					else if (string.IsNullOrWhiteSpace (sSecondary))
						_dataGrid.SetRowColor (iter, clrMissingSecond, true);
					else 
						_dataGrid.SetRowColor (iter, clrWhite, false);																								
					
				} while (store.IterNext(ref iter));
			} // if
		}		
	}
	
}

